package com.example.springboot.Controller;

import com.example.springboot.Service.ExcelService;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @auther gxnualbert
 * @create 2021-04-17-11:44
 */

@Controller
public class downloadExcel {

    @Autowired
    private ExcelService excelService;

    @GetMapping("download/excel")
    public ResponseEntity<byte[]> getExcel() throws IOException {
//        String realPath = "D://excel_demo.xlsx";
        String realPath = "D://中文test.txt";
        File tmpFile = new File(realPath);
        String fileName = tmpFile.getName();

        HttpHeaders headers = new HttpHeaders();

        headers.set("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        // 根据文件路径 封装成文件输入流
        InputStream in = new FileInputStream(realPath);

        String hello = "this is hello";
        hello.getBytes(StandardCharsets.UTF_8);
//        return new ResponseEntity<>(hello.getBytes(StandardCharsets.UTF_8),headers, HttpStatus.OK);
        return new ResponseEntity<>(new byte[in.available()], headers, HttpStatus.OK);
    }

    @GetMapping("/serverlet")
    public void serverletDownload(HttpServletResponse response) throws IOException {
        String realPath = "D://excel_demo.xlsx";  // 把excel 文件放在这个目录下面
        File tmpFile = new File(realPath);
        String fileName = tmpFile.getName();
        InputStream in = new FileInputStream(realPath);// 根据文件路径 封装成文件输入流。 把磁盘文件，转换为输入流，存入到内存中
        int len = 0;
        byte[] buffer = new byte[1024];// 声明了一个1KB的字节 的缓冲区
        // 设置响应头 content-disposition： 就是设置文件下载的打开方式，默认会在网页上打开，
        // 设置attachment;filename= 就是为了以下载方式来打开文件
        // "UTF-8"设置如果文件名有中文就不会乱码
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        OutputStream out = response.getOutputStream(); // 获取输出流
        // 循环读取文件，每次读1KB，避免内存溢出
        while ((len = in.read(buffer)) > 0) { // 从缓冲区读取内容
            out.write(buffer, 0, len);// // 往客户端写入 将缓冲区的数据输出到客户端浏览器
        }
        in.close();
    }

    @GetMapping("/zipFile")
    public void getZipFile(HttpServletResponse response) throws IOException {
        // refrence：https://blog.csdn.net/u013055490/article/details/87604705
        //需要压缩的文件
        List<XSSFWorkbook> workbookList = new ArrayList<>();
        workbookList.add(excelService.getWorkbook("a", "AAAAAAAAAAA"));
        workbookList.add(excelService.getWorkbook("B", "BBBBBBBBBBB"));
        workbookList.add(excelService.getWorkbook("c", "CCCCCCCCCCC"));
        workbookList.add(excelService.getWorkbook("d", "DDDDDDDDDDD"));

        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("allExcel.zip", "UTF-8"));
        OutputStream outputStream = response.getOutputStream(); // 获取输出流

        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(outputStream);
        zous.setUseZip64(Zip64Mode.AsNeeded);

        for (XSSFWorkbook xssfWorkbook : workbookList) {
            String fileName = UUID.randomUUID() + ".xlsx";//给文件名
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            xssfWorkbook.write(baos);
            byte[] bytes = baos.toByteArray();


            ArchiveEntry entry = new ZipArchiveEntry(fileName);
            zous.putArchiveEntry(entry);

            zous.write(bytes);
            zous.closeArchiveEntry();

            if (baos != null) {
                baos.close();
            }
        }
        zous.close();
    }

    @GetMapping("/ResponseEntity")
    public ResponseEntity<byte[]> downloadResponEntity() throws IOException {
        // reference:https://blog.csdn.net/dd_king/article/details/78844408

        Map<String, XSSFWorkbook> excelMap = new HashMap<>();
        excelMap.put("脱敏审核", excelService.getWorkbook("脱敏审核", "1AAAAAA脱敏审核AAAAA"));
        excelMap.put("敏感建筑审核", excelService.getWorkbook("敏感建筑审核", "1AAAAAA敏感建筑审核AAAAA"));
        excelMap.put("task统计", excelService.getWorkbook("task统计", "1AAAAAAtask统计AAAAA"));

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 获取输出流. 下面的要锁流，会往这个输出流写内容

        ZipArchiveOutputStream zous = new ZipArchiveOutputStream(outputStream);

        zous.setUseZip64(Zip64Mode.AsNeeded);

        for (String key : excelMap.keySet()) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            excelMap.get(key).write(baos);  // 1. 从 map中获取每个excel 文件，通过write的形势，把内容输出到ByteArrayOutputStream
            byte[] bytes = baos.toByteArray(); // 2. ByteArrayOutputStream 拿到之后，转换为字节数组

            ArchiveEntry entry = new ZipArchiveEntry(key + ".xlsx"); //  key+ ".xlsx"表示每个单独的file 文件的命名
            zous.putArchiveEntry(entry);
            zous.write(bytes); // 3 往压缩文件写字节数组。估计要用缓冲区。文件不大，应该不会把内存搞爆！
            zous.closeArchiveEntry();

            if (baos != null) {
                baos.close();
            }
        }
        zous.close();

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attchement;filename=" + URLEncoder.encode("allExcel.zip", "UTF-8"));
        return new ResponseEntity<byte[]>(outputStream.toByteArray(), headers, HttpStatus.OK);

    }
}
